package cm.service.impl;

import cm.dto.XxlJobInfoDTO;
import cm.dto.XxlJobInfoEntity;
import cm.dto.XxlJobInfoExportDTO;
import cm.dto.XxlJobInfoQueryDTO;
import cm.mapper.XxlJobInfoMapper;
import cm.processor.XxlJobAnnotationProcessor;
import cm.service.XxlJobInfoService;
import cm.util.XxlJobParser;
import cm.vo.XxlJobInfoPlusVO;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 业务实现类
 * @since 2025-09-03 11:54:16
 */
@Slf4j
@Service
public class XxlJobInfoServiceImpl extends ServiceImpl<XxlJobInfoMapper, XxlJobInfoEntity>
        implements XxlJobInfoService {
        
    @Autowired
    private XxlJobInfoMapper xxlJobInfoMapper;

    @Autowired
    private XxlJobAnnotationProcessor xxlJobAnnotationProcessor;

    @Override
    public void exportAllJobsWithServiceName(HttpServletResponse response, XxlJobInfoQueryDTO xxlJobInfoQueryDTO) {
        Integer jobGroup = xxlJobInfoQueryDTO.getJobGroup();
        List<XxlJobInfoEntity> xxlJobInfoEntityList = xxlJobInfoMapper.selectList(new LambdaQueryWrapper<XxlJobInfoEntity>()
                .eq(XxlJobInfoEntity::getJobGroup, jobGroup)
                .eq(XxlJobInfoEntity::getTriggerStatus, 1)
        );
        List<XxlJobInfoExportDTO> exportDTOList = Convert.toList(XxlJobInfoExportDTO.class, xxlJobInfoEntityList);
        Map<String, XxlJobInfoDTO> jobHandlerMap = xxlJobAnnotationProcessor.getJobHandlerMap();
        exportDTOList.forEach(exportDTO -> {
            XxlJobInfoDTO jobInfo = jobHandlerMap.get(exportDTO.getExecutorHandler());
            if (jobInfo != null) {
                exportDTO.setServiceName(jobInfo.getServiceName());
            }
        });
        ExcelTools.export(response, "调度任务列表", exportDTOList);
    }

    @Override
    public void exportJobsByServiceName(HttpServletResponse response, XxlJobInfoQueryDTO xxlJobInfoQueryDTO) {
        Integer jobGroup = xxlJobInfoQueryDTO.getJobGroup();
        String serviceName = xxlJobInfoQueryDTO.getServiceName();
        // 模拟从Excel读取的数据 - 实际应用中应该使用POI等库读取Excel
        List<XxlJobInfoEntity> xxlJobInfoEntityList = xxlJobInfoMapper.selectList(new LambdaQueryWrapper<XxlJobInfoEntity>()
                .eq(XxlJobInfoEntity::getJobGroup, jobGroup)
                .eq(XxlJobInfoEntity::getTriggerStatus, 1)
        );

        List<XxlJobInfoDTO> jobInfoDTOList = Convert.toList(XxlJobInfoDTO.class, xxlJobInfoEntityList);

        // 分析每个任务的每日执行时间
        List<XxlJobInfoDTO> jobScheduleList = XxlJobParser.analyzeJobList(jobInfoDTOList);

        Map<String, XxlJobInfoDTO> jobHandlerMap = xxlJobAnnotationProcessor.getJobHandlerMap();

        // 补充任务所属服务名
        List<XxlJobInfoExportDTO> exportDTOList = new ArrayList<>();
        jobScheduleList.forEach(xxlJobInfoDTO -> {
            XxlJobInfoDTO jobInfo = jobHandlerMap.get(xxlJobInfoDTO.getExecutorHandler());
            if (jobInfo != null) {
                if (Objects.equals(jobInfo.getServiceName(), serviceName)) {
                    xxlJobInfoDTO.setServiceName(serviceName);
                    XxlJobInfoExportDTO exportDTO = Convert.convert(XxlJobInfoExportDTO.class, xxlJobInfoDTO);
                    exportDTOList.add(exportDTO);
                }
            }
        });

        String filePrefix = String.format("调度任务列表(%s)", serviceName);
        ExcelTools.export(response, filePrefix, exportDTOList);
    }

    @Override
    public XxlJobInfoPlusVO detail(Long id) {
        XxlJobInfoPlusVO xxlJobInfoPlusVO = this.xxlJobInfoMapper.selectDetail(id);
        return xxlJobInfoPlusVO;
    }
    
    @Override
    public List<XxlJobInfoEntity> listByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            log.warn("ids为空");
            return new ArrayList<>();
        }
        List<XxlJobInfoEntity> xxlJobInfoEntityList = this.list(new LambdaQueryWrapper<XxlJobInfoEntity>()
                .in(XxlJobInfoEntity::getId, ids)
        );
        return xxlJobInfoEntityList;
    }
    
    @Override
    public Map<Long, XxlJobInfoEntity> mapByIds(List<Long> ids) {
        List<XxlJobInfoEntity> xxlJobInfoEntityList = listByIds(ids);
        Map<Long, XxlJobInfoEntity> xxlJobInfoDTOMap = ConvertTools.toMap(XxlJobInfoEntity::getId, xxlJobInfoEntityList);
        return xxlJobInfoDTOMap;
    }
}
